home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
A Teacher's Guide to the Holocaust
/
A Teacher's Guide to the Holocaust.iso
/
data
/
people
/
scripts
/
interactionclass.js
< prev
next >
Wrap
Text File
|
1999-12-05
|
19KB
|
568 lines
// Copyright 1998,1999 Macromedia, Inc. All rights reserved.
// Localization strings
var TRACK_system_not_found = "Tracking system not found.";
//Constructs an Interaction
function MM_interaction(theSelf,
theJudgeOnSel, theAllowMultiSel, theAllThatApply, theUnknownIsCorrect,
theDisabled, theTriesLimit, theTimeLimit,
theTrackIntId, theTrackObjectiveId,
theTrackQType,theTrackWeight, theKTrack) {
// properties
this.judgeOnSel = theJudgeOnSel;
this.allowMultiSel = theAllowMultiSel;
this.allThatApply = theAllThatApply;
this.unknownIsCorrect = theUnknownIsCorrect;
this.disabled = theDisabled;
this.tries = 0;
this.triesLimit = (theTriesLimit)?theTriesLimit:0;
this.triesAtLimit = false;
this.time = 0;
this.timeLeft = 0;
this.timeLimit = (theTimeLimit)?theTimeLimit:0;
this.timeAtLimit = false;
this.trackIntId = theTrackIntId;
this.trackObjectiveId = theTrackObjectiveId;
this.trackQType = theTrackQType;
this.trackWeight = theTrackWeight;
this.knowledgeTrack = theKTrack;
this.totalElems = 0;
this.possCorrect = 0;
this.possIncorrect = 0;
this.knownResponse = false;
this.totalCorrect = 0;
this.totalIncorrect = 0;
this.correct = false;
this.score = 0;
this._self = theSelf;
this._timeStart = 0;
this._timerID = 0;
this.browserIsNS = (navigator.appName.indexOf('Netscape') != -1);
this.browserIsIE = (navigator.appName.indexOf('Microsoft') != -1);
this.osIsWindows = (navigator.appVersion.indexOf('Win') != -1);
this.osIsMac = (navigator.appVersion.indexOf('Mac') != -1); // ????
this.browserVersion = parseFloat(navigator.appVersion);
this.e = new Array();
this.b = new Array();
// methods
this.init = MM_intInit;
this.reset = MM_intReset;
this.resetElems = MM_intResetElems;
this.enable = MM_intEnable;
this.disable = MM_intDisable;
this.setDisabled = MM_intSetDisabled;
this.update = MM_intUpdate;
this.add = MM_intAdd;
this.setTries = MM_intSetTries;
this.setTriesLimit = MM_intSetTriesLimit;
this.setTime = MM_intSetTime;
this.setTimeLimit = MM_intSetTimeLimit;
this.track = MM_intTrack
this.getTime = MM_intGetTime;
this.am = MM_intAm;
this.judge = MM_intJudge;
this.resetActionMgr = MM_intResetActionMgr;
this.setSegmNode = MM_intSetSegmNode;
this.getSegmNode = MM_intGetSegmNode;
this.setSegmDisabled = MM_intSetSegmDisabled;
this.getSegmDisabled = MM_intGetSegmDisabled;
}
//Calls the element init funtions if they exist, and then does a reset
function MM_intInit() {
var i,j,localPC;
with (this) {
// init elems, and set totalElems, possCorrect, possIncorrect;
totalElems = 0;
possCorrect = 0;
possIncorrect = 0;
for (i in e) if (i != 'length') {
if (e[i].init != null) e[i].init();
totalElems++;
localPC = 0;
for (j in e[i].c) if (j != 'length' && e[i].c[j].isCorrect != null)
(e[i].c[j].isCorrect) ? localPC++ : possIncorrect++;
if (e[i]._singleChoice != null && localPC > 1)
localPC = 1;
possCorrect += localPC;
}
reset();
if (knowledgeTrack) {
var frm = findcmiframe(null);
if (frm == null) {
installcmi(window); //layers in NS
if (!CMIIsPresent()) {
var cmi = cmiinit(window);
if (cmi) CMIInitialize();
else if (!window.trackwarning) {
alert(TRACK_system_not_found);
window.trackwarning = true;
} } }
else {
if (window.CMIInitialize == null) frm.installcmi(window);
if (window.CMIInitialize != null) CMIInitialize();
if (!CMIIsPresent() && !window.trackwarnings) {
alert(TRACK_system_not_found);
window.trackwarning = true;
} } } }
window["'"+this._self+"'"] = this._self; //redeclare global on window in case inserted in layer
}
//Called to reset the interaction
function MM_intReset() {
with (this) {
tries = 0;
triesAtLimit = false;
_timeStart = Math.floor((new Date()).getTime()/1000);
if (_timerID) clearTimeout(_timerID);
if (!disabled && timeLimit) _timerID = setTimeout(_self+".judge()",(timeLimit+1)*1000);
time = 0;
timeLeft = timeLimit;
timeAtLimit = false;
resetActionMgr();
resetElems();
update(true);
}
}
//Calls the reset for the individual elements
function MM_intResetElems() {
with (this) {
for (var i in e) if (i != 'length')
if (e[i].reset != null) e[i].reset();
update(true);
}
}
//Enables the interaction
function MM_intEnable() {
if (this.disabled) with (this) {
_timeStart = Math.floor((new Date()).getTime()/1000) - time;
if (timeLimit)
_timerID = setTimeout(_self+".judge()",Math.max(0,(timeLimit-time)+1)*1000);
disabled = false;
update(true);
for (var i in e) if (i != 'length')
if (e[i].enable != null) e[i].enable();
}
}
//Disables the interaction
function MM_intDisable() {
if (!this.disabled) with (this) {
update(true); // update 'time'
if (_timerID) clearTimeout(_timerID); // clear the timer
disabled = true;
for (var i in e) if (i != 'length')
if (e[i].disable != null) e[i].disable();
}
}
//Calls the approppriate disable or enable function
function MM_intSetDisabled(theDisabled) {
if (theDisabled) this.disable();
else this.enable();
}
//Update the interaction state
// Note: tries will be updated by the judge method, and time will
// be updated by both this method and the judge method.
function MM_intUpdate(noJudge) {
if (!this.disabled) with (this) {
knownResponse = false;
totalCorrect = 0;
totalIncorrect = 0;
correct = false;
score = 0;
for (var i in e) if (i != 'length') {
for (var j in e[i].c) if (j != 'length') {
if (e[i].c[j].selected) {
knownResponse = true;
score += e[i].c[j].score;
if (e[i].c[j].isCorrect != null)
(e[i].c[j].isCorrect) ? totalCorrect++ : totalIncorrect++;
} } }
if (!knownResponse) correct = unknownIsCorrect;
else if (totalIncorrect != 0) correct = false;
else if (totalCorrect == 0) correct = null; // not judged
else correct = (!allThatApply || totalCorrect >= possCorrect);
time = Math.floor((new Date()).getTime()/1000) - _timeStart;
if (timeLimit && !timeAtLimit) {
timeLeft = Math.max(0, timeLimit - time);
timeAtLimit = (time > timeLimit);
}
if (judgeOnSel && !noJudge) judge();
}
}
function MM_intSetTries(theTries) {
with (this) {
tries = theTries;
triesAtLimit = (triesLimit) ? (tries >= triesLimit) : false;
}
}
function MM_intSetTriesLimit(theTriesLimit) {
with (this) {
triesLimit = theTriesLimit;
triesAtLimit = (triesLimit) ? (tries >= triesLimit) : false;
}
}
function MM_intSetTime(theTime) {
with (this) {
time = Math.max(0, theTime);
_timeStart = Math.floor((new Date()).getTime()/1000) - time;
timeLeft = (timeLimit) ? Math.max(0, timeLimit - time) : timeLimit;
timeAtLimit = (timeLimit) ? (time > timeLimit) : false;
if (_timerID) clearTimeout(_timerID); // clear the timer
if (!disabled && timeLimit)
_timerID = setTimeout(_self+".judge()",Math.max(0,(timeLimit-time)+1)*1000);
}
}
function MM_intSetTimeLimit(theTimeLimit) {
with (this) {
if (!disabled)
time = Math.floor((new Date()).getTime()/1000) - _timeStart;
timeLimit = theTimeLimit;
timeLeft = (timeLimit) ? Math.max(0, timeLimit - time) : timeLimit;
timeAtLimit = (timeLimit) ? (time > timeLimit) : false;
if (_timerID) clearTimeout(_timerID); // clear the timer
if (!disabled && timeLimit)
_timerID = setTimeout(_self+".judge()",Math.max(0,(timeLimit-time)+1)*1000);
}
}
function MM_intAdd(theType, A, B, C, D, E, F, G, H, I, J, K, L, M) {
var theObj = eval("new MM_" + theType + "(" + this._self + ", A, B, C, D, E, F, G, H, I, J, K, L, M)");
if (theObj._isChoice != null)
this.e[A].c[B] = theObj;
else
this.e[A] = theObj;
}
function MM_intTrack() {
var aDt= new Date();
var curHr=aDt.getHours()+'', curMin=aDt.getMinutes()+'', curSec=aDt.getSeconds()+'';
var curDay=aDt.getDate()+'', curMonth=aDt.getMonth()+1+'', curYear=aDt.getYear(), dmy;
var lat = Math.floor(aDt.getTime()/1000) - this._timeStart;
var x=3600;
var y=60;
var hrs=Math.round(lat/x - lat%x/x)+'';
var min=Math.round((lat-hrs*x)/y-(lat-hrs*x)%y/y)+'';
var sec=Math.round(lat-hrs*x-min*y)+'';
var sRes,cRes,res,aName,bName,isC,isNC,isSel,iType;
if (curYear < 1900) curYear += 1900;
if (curDay.toString().length==1) curDay = '0'+curDay;
if (curMonth.toString().length==1) curMonth = '0'+curMonth;
dmy = curDay+"/"+curMonth+"/"+curYear;
sRes=cRes=res=aName=bName=""
with (this) {
if (trackQType.length==0) return;
iType=trackQType.charAt(0).toLowerCase();
if (allThatApply&&possCorrect>1) sRes=cRes='{';
for (var i in e) if (i != 'length') {
for (var j in e[i].c) if (j != 'length') {
isC=e[i].c[j].isCorrect;
isSel=e[i].c[j].selected;
if (iType=='m') {
aName=e[i].c[j]._elem._name;
bName=e[i].c[j]._target._name;
if (isC) cRes+=aName+'.'+bName+',';
if (isSel) sRes+=aName+'.'+bName+',';
}
else if (iType=='f') {
aName=e[i].value;
bName=MM_textDeencrypt(e[i].c[j].expectedValue);
if (isC) cRes+=bName+',';
if (isSel) sRes+=aName+',';
}
else if ((iType=='c')||(iType=='t')) {
if (e[i]._trkObj!=null) {
aName=e[i].c[j].expectedValue;
x=aName.indexOf(':');
aName=aName.substring(0,x)+'-'+aName.substring(x+1,aName.length)
bName=e[i].value
}
else if (e[i]._tick!=null) {
aName=e[i].c[j].expectedValue;
if (isSel) bName = aName;
}
else if (e[i]._stateMask!=null && totalElems==1) {
aName=e[i].expectedValue;
bName=e[i].value;
}
else
aName=bName=e[i].c[j]._name;
if (isC) cRes+=aName+',';
if (isSel) sRes+=bName+',';
}
else {
aName=bName='';
if (isC) cRes+=',';
if (isSel) sRes+=',';
}
isNC=(isC==false)&&isSel;
isC=isC&&isSel;
if (possCorrect>1) res=res+(isC?'c,':isNC?'w,':isSel?'n,':'');
else if (isSel) res = isC?'c':isNC?'w':'n';
}
}
if (sRes.charAt(sRes.length-1)==',') sRes=sRes.substring(0,sRes.length-1);
if (cRes.charAt(cRes.length-1)==',') cRes=cRes.substring(0,cRes.length-1);
if (res.charAt(res.length-1)==',') res=res.substring(0,res.length-1);
if (allThatApply&&possCorrect>1) {
sRes=sRes+'}';
cRes=cRes+'}';
}
if (window.CMIIsPresent && CMIIsPresent()) {
if (hrs.toString().length==1) hrs = '0'+hrs;
if (min.toString().length==1) min = '0'+min;
if (sec.toString().length==1) sec = '0'+sec;
if (curHr.toString().length==1) curHr = '0'+curHr;
if (curMin.toString().length==1) curMin = '0'+curMin;
if (curSec.toString().length==1) curSec = '0'+curSec;
CMIAddInteraction(dmy, curHr+":"+curMin+":"+curSec,
trackIntId, trackObjectiveId, trackQType,
cRes, sRes, res, trackWeight, hrs+":"+min+":"+sec);
}
}
}
function MM_intGetTime() {
var date = new Date();
this.time = (date.getTime()/1000 - this._timeStart)*1000;
return this.time/1000;
}
//Finds any object in either browser using recursion.
//Only pass the first argument, the name of the object to find.
//Returns a pointer the object if found, else an empty string.
// MM_intFindObject('bar') returns the object
// document.layers['foo'].document.layers['bar']
function MM_intFindObject(objName, parentObj) {
var i,tempObj="",found=false,curObj = "";
var NS = (navigator.appName.indexOf("Netscape") != -1);
if (!NS && document.all) curObj = document.all[objName]; //IE4
if (!curObj) {
parentObj = (parentObj != null)? parentObj.document : document;
if (parentObj[objName] != null) curObj = parentObj[objName]; //at top level
else { //if in form
if (parentObj.forms) for (i=0; i<parentObj.forms.length; i++) { //search level for form object
if (parentObj.forms[i][objName]) {
curObj = parentObj.forms[i][objName];
found = true; break;
} }
if (!found && NS && parentObj.layers && parentObj.layers.length > 0) {
parentObj = parentObj.layers;
for (i=0; i<parentObj.length; i++) { //else search for child layers
tempObj = MM_intFindObject(objName,parentObj[i]); //recurse
if (tempObj) { curObj = tempObj; break;} //if found, done
} } } }
return curObj;
}
//Called from within conditions to check document properties
function MM_getDocProp(theName, theProp, theType) {
var theObj = MM_intFindObject(theName);
if (theObj) return eval('theObj.' + theProp);
else return null;
}
//********* ACTION MGR METHODS *********
function MM_intJudge(treeRoot,curRoot,level) {
var i=0,theNode,retVal=true,firstCond = true;
level = (curRoot == null)?0:level+1;
if (!level) {
curRoot = this; //set tree to highest level
if (this.disabled) retVal=false;
else {
this.time = Math.floor((new Date()).getTime()/1000) - this._timeStart;
if (this.timeLimit && !this.timeAtLimit) {
this.timeLeft = Math.max(0, this.timeLimit - this.time);
this.timeAtLimit = (this.time > this.timeLimit);
}
this.tries++;
if (this.triesLimit)
this.triesAtLimit = (this.tries >= this.triesLimit);
} } else if (treeRoot.curNode != null && curRoot == treeRoot.curNode) //if at curNode
i = treeRoot.curIndex; //offset by index
for (i; (retVal && i<curRoot.b.length); i++) {
theNode = curRoot.b[i];
if (this.disabled) retVal=false;
else if (theNode.disabled) continue;
else if (theNode.type == "segm") { //SEGMENT
curNode = (theNode.curNode)?theNode.curNode:theNode;
if (curNode != 'done')
retVal = MM_intJudge(theNode,curNode,level); //start from that node
else if (!level) continue;
} else if (theNode.type == 'cond') { //CONDITION
if (eval(theNode.data)) {
if (!treeRoot.data) treeRoot.curNode = 'done'; //if not "auto-reset tree", set curNode
retVal = MM_intJudge(treeRoot,theNode,level);
if (level) break;
} else if (firstCond) {
firstCond = false;
if (!treeRoot.data) {treeRoot.curNode = curRoot; treeRoot.curIndex = i;}
}
} else if (theNode.type == 'actn') { //ACTION
if (!treeRoot.data) //not auto-reset
if (i<(curRoot.b.length-1)) { //not last node
treeRoot.curNode = curRoot; treeRoot.curIndex = i+1; //set curNode to next node
} else treeRoot.curNode = 'done'; //last node, clear curNode
if (theNode.data == 'stop') retVal=false; //STOP
else eval(theNode.data);
} }
if (!level && curRoot!=null && curRoot.knowledgeTrack) curRoot.track();
return retVal
}
//Disables or enables ActionMgr segments. If no segment passed,
//disables *all* segments. Returns false if segment not found.
function MM_intSetSegmDisabled(segmName,disable) {
var i, retVal=false;
for (i=0; i<this.b.length; i++) //search for segment
if (!segmName || this.b[i].name==segmName) {
this.b[i].disabled=disable; retVal = true;
if (segmName) break;
}
return retVal
}
//Returns the disabled flag from an ActionMgr segment.
//Returns null if segment not found.
function MM_intGetSegmDisabled(segmName) {
var i, retVal=null;
for (i=0; i<this.b.length; i++) //search for segment
if (this.b[i].name==segmName) {
retVal = this.b[i].disabled; break;
}
return retVal
}
function MM_intResetActionMgr(segmName) {
var i;
if (segmName != null) MM_intTreeSetCurNode(segmName,null,this); //clear single curNode
else for (i=0;i<this.b.length;i++) this.b[i].curNode = null; //clear all curNodes
}
function MM_intSetSegmNode(segmName,condName) {
var i, curRoot=null;
if (!condName) this.resetActionMgr(segmName);
else {
for (i=0; i<this.b.length; i++) //search for segment, set as curRoot
if (this.b[i].name == segmName) { curRoot = this.b[i]; break; }
MM_intTreeSetCurNode(condName,null,curRoot,curRoot);
}
}
function MM_intTreeSetCurNode(nodeName,newVal,treeRoot,curRoot) {
var i,theNode;
if (curRoot==null) curRoot = treeRoot; //if first time, use treeRoot
for (i=0; i<curRoot.b.length; i++) {
theNode = curRoot.b[i];
if (theNode.type == "segm") { //SEGMENT
if (theNode.name == nodeName) theNode.curNode = newVal;
else MM_intTreeSetCurNode(nodeName,newVal,theNode,theNode);
} else if (theNode.type == 'cond') { //CONDITION
if (theNode.name == nodeName) { //if name found
treeRoot.curNode = curRoot; treeRoot.curIndex = i;
break;
} else MM_intTreeSetCurNode(nodeName,newVal,treeRoot,theNode);
} }
}
//Returns the current node for the given Segment, returned as:
// top of segment - "" (empty string)
// middle of segment - condition name
// end of segment - "done"
function MM_intGetSegmNode(segmName) {
var i, curNode='';
for (i=0; i<this.b.length; i++) //search for segment
if (this.b[i].name == segmName) {
curNode = this.b[i].curNode;
if (curNode==null) curNode = "";
else if (curNode!="done") curNode = curNode.b[this.b[i].curIndex].name;
break;
}
return curNode
}
//********* ACTION MGR NODE CLASS *********
function MM_intNode(theType,theName,theData) {
this.type = (theType)?theType:'';
this.name = (theName)?theName:'';
this.data = (theData)?theData:'';
this.b = new Array();
}
//Create Action Manager (tree)
function MM_intAm(theType,theName,theData) {
if (theType == "segm") {
if (!this.tParent) { //initialize system
this.tParent = new Array(); //tree parent nodes
this.tIndex = new Array(); //child indexes
this.tIndex[0] = -1; //set index for root depth
}
this.tLevel = 0; //reset level to 0
this.tIndex[this.tLevel]++; //increment the index
this.b[this.tIndex[this.tLevel]] = new MM_intNode("segm", theName,theData); //create tree
this.tParent[this.tLevel] = this.b[this.tIndex[this.tLevel]]; //put this tree root at top level
this.tIndex[this.tLevel+1] = -1; //reset child level index
} else if (theType == "actn") {
var parentNode = this.tParent[this.tLevel]; //get parent
var levelIndex = ++this.tIndex[this.tLevel+1]; //get index
parentNode.b[levelIndex] = new MM_intNode('actn',theName,theData); //add action
} else if (theType == "cond") {
var parentNode = this.tParent[this.tLevel]; //get parent
var levelIndex = ++this.tIndex[this.tLevel+1]; //get index
parentNode.b[levelIndex] = new MM_intNode('cond',theName,theData); //add condition
this.tLevel++; //go down a level
this.tParent[this.tLevel] = parentNode.b[levelIndex]; //save this node as parent
this.tIndex[this.tLevel+1] = -1; //reset child level index
} else if (theType == "end") {
this.tLevel--; //go up a level
}
}